<template>
  <div class="chat-app">
    <!-- 顶部栏 -->
    <el-header class="chat-header">
      <div class="user-info">
        <span>{{ userInfo.name }}</span>
      </div>
      <el-button size="mini" type="danger" @click="logout">退出</el-button>
    </el-header>

    <!-- 主体区域 -->
    <div class="chat-body">
      <!-- 会话列表 -->
      <el-aside width="220px" class="chat-sidebar">
        <div class="sidebar-title">会话列表</div>
        <el-menu class="session_menu" :default-active="activeSessionId" @select="selectSession">
          <el-menu-item v-for="session in sessions" :key="session.id" :index="session.id">
            {{ session.title }}
          </el-menu-item>
        </el-menu>
        <div class="sidebar-footer">
          <el-button type="primary" style="width: 100%" icon="el-icon-plus" @click="createSession">
            新的会话
          </el-button>
        </div>
      </el-aside>

      <div class="chat-msg">
        <!-- 聊天内容区 -->
        <div class="chat-main" ref="chatContent">
          <div class="chat-messages" v-if="activeSessionId">
            <div v-for="(msg, index) in messages" :key="index"
                 :class="['message-row', msg.role === 'USER' ? 'user' : 'ai']">
              <div class="avatar">{{ msg.role === 'USER' ? '我' : 'AI' }}</div>
              <div class="message-bubble" v-html="renderedContent(msg.content)"></div>
            </div>
          </div>
          <div v-else style="padding: 40px; color: #999; text-align: center;">
            您好，{{ userInfo.name }},请开始我们的对话！
          </div>
        </div>

        <!-- 输入框 -->
        <div class="chat-input-area">
          <div class="chat-input-text"
               data-placeholder="请输入内容..."
               contenteditable="true"
               onkeydown="if(event.keyCode===13) {document.getElementById('sendBtn').click();return false;}"
          ></div>

          <div class="quick-msg-label">
            <span
                class="quick-msg-label-tag"
                v-for="(text, index) in defaultMessages"
                :key="index"
                @click="sendQuickMessage(text)">
              {{ text }}
            </span>
          </div>
          <div class="chat-input-send">
            <el-button type="primary"
                       size="small"
                       @click="sendBtn"
                       id="sendBtn"
                       :disabled="msgLoading"
            >发送
            </el-button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import * as u from "@/util/util";
import * as c from "@/util/config";
import {renderWithKatex} from "@/util/katexRender";
import {marked} from 'marked';

export default {
  data() {
    return {
      userInfo: u.getSession(c.sessionKey.USER_INFO),
      //输入框
      input: '',
      //当前选中的会话
      activeSessionId: '',
      //会话集合
      sessions: [],
      //当前回话消息列表
      messages: [],
      //默认消息
      defaultMessages: [], // 默认插入消息
      //消息发送中
      msgLoading: false,
    };
  },

  created() {
    this.init();
  },

  methods: {
    init() {
      //获取会话
      this.getSession();
      this.$HttpService.get("/common/getItem/ai_quick_question").then(res => {
        this.defaultMessages = res.map(x => {
          return x.label;
        })
      })

    },

    /**
     * 解析LaTeX 数学公式，
     * 解析m
     * @param text
     * @returns {*}
     */
    renderedContent(text) {
      if(!text){
        return ""
      }
      let html = renderWithKatex(text)
      html = marked(html || '');
      return html;
    },

    /**
     * 获取会话
     */
    getSession() {
      this.$HttpService.get("/ai-chat-session/findListByUser").then(res => {
        this.sessions = res;
      });
    },

    /**
     * 获取会话ID
     */
    getSessionId(fun) {
      //判断是否存在选中的主键id
      if (!this.activeSessionId) {
        this.$HttpService.get("/ai-chat-session/getSessionId").then(res => {
          this.activeSessionId = res;
          fun(res);
        });
      } else {
        fun(this.activeSessionId);
      }
    },

    /**
     * 发送按钮激活
     */
    sendBtn() {
      const el = this.$el.querySelector('.chat-input-text');
      const content = el.innerText.trim();
      this.sendMessage(content)
      el.innerText = '';
    },


    /**
     * 发送消息
     */
    sendMessage(msg) {
      if (!msg) return;
      //如果会话id为空
      this.getSessionId(() => {
        //用户发送消息
        this.messages.push({role: 'USER', content: msg});
        //默认插入一个ai回复的空内容
        this.messages.push({role: 'AI', content: ""});
        this.scrollToBottom();
        this.msgLoading = true;
        u.streamPost(
            "/ai/streamMemory",
            {msg: msg, sessionId: this.activeSessionId},
            chunk => {
              let message = this.messages[this.messages.length - 1];
              if (message) {
                message.content += chunk;
              }
              this.scrollToBottom();
            },
            //消息发送中回调
            full => {
              this.msgLoading = false;
            },
            chunk => {
              //处理第一次读,更新会话列表
              this.getSession();
            }
        )
      });
    },


    //创建一个会话
    createSession() {
      this.activeSessionId = "";
      this.messages = [];
    },

    /**
     * 切换选中的会话
     * @param id
     */
    selectSession(id) {
      this.activeSessionId = id;
      this.$HttpService.get(`/ai-chat-message/findMessageBySessionId/${id}`).then(res => {
        this.messages = res;
        this.scrollToBottom();
      });
    },

    /**
     * 消息框滚到底部
     */
    scrollToBottom() {
      this.$nextTick(() => {
        setTimeout(() => {
          const el = this.$refs.chatContent;
          if (el) {
            el.scrollTo({
              top: el.scrollHeight,
              behavior: 'smooth'  // 平滑滚动关键参数
            });
          }
        }, 50); // 延迟渲染完成
      });
    },

    /**
     * 发送默认消息
     */
    sendQuickMessage(content) {
      this.sendMessage(content)
      this.scrollToBottom();
    },

    /**
     * 退出登录
     */
    logout() {
      this.$message.success('已退出登录');
    },
  }
};
</script>

<style scoped lang="scss">
.chat-app {
  display: flex;
  flex-direction: column;
  height: 100vh;
  width: 100%;
  color: #333;
}

.chat-header {
  height: 60px;
  background: #f5f5f5;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0 20px;
  border-bottom: 1px solid #ebeef5;

  .user-info {
    font-weight: bold;
    font-size: 16px;
    color: #333;
  }
}

.chat-body {
  height: calc(100% - 60px);
  max-height: calc(100% - 60px);
  display: flex;
  overflow: hidden;

  .chat-sidebar {
    height: 100%;
    max-height: 100%;
    background: #fff;
    border-right: 1px solid #ebeef5;
    display: flex;
    flex-direction: column;
    .session_menu {
      flex: 1;
      overflow: hidden;
      overflow-y: auto;
    }
    .sidebar-title {
      padding: 10px;
      font-weight: bold;
      font-size: 15px;
      border-bottom: 1px solid #ebeef5;
    }
    .sidebar-footer {
      padding: 30px 0;
      width: 80%;
      margin: 0 auto;
    }
  }


  .chat-msg {
    width: 100%;
    height: 100%;
    max-height: 100%;
    display: flex;
    flex-direction: column;

    .chat-main {
      height: calc(100% - 150px);
      background: #fcfcfc;
      padding: 20px;
      overflow: hidden;
      overflow-y: auto;

      .chat-messages {
        height: 100%;

        .message-row {
          display: flex;
          margin-bottom: 16px;
          align-items: flex-start;

          &.user {
            justify-content: flex-end;

            .avatar {
              order: 2;
              margin-left: 8px;
              background-color: #409eff;
            }

            .message-bubble {
              background-color: #d0ebff;
              color: #1f2d3d;
            }
          }

          &.ai {
            justify-content: flex-start;

            .avatar {
              background-color: #909399;
              margin-right: 8px;
            }

            .message-bubble {
              background-color: #f0f0f0;
              color: #555;
            }
          }

          .avatar {
            width: 32px;
            height: 32px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 14px;
            color: #fff;
          }

          .message-bubble {
            max-width: 70%;
            border-radius: 16px;
            font-size: 15px;
            box-sizing: border-box;
            padding: 20px !important;
          }
        }
      }
    }

    .chat-input-area {
      width: 90%; // 放宽输入区域
      height: 150px;
      margin: 10px auto;
      background: white;
      font-size: 16px;
      display: flex;
      flex-direction: column;
      border-radius: 10px;
      padding: 10px;

      .chat-input-text {
        flex: 1;
        min-height: 60px;
        padding: 10px;
        overflow-y: auto;
        outline: none;
        border: 1px solid #ddd;
        border-radius: 6px;
        margin-bottom: 8px;
      }

      .quick-msg-label-tag {
        color: #29AAE3;
        margin-left: 30px;
        cursor: pointer;
        transition: color 0.3s ease; /* 添加颜色过渡动画，持续0.3秒 */
        font-weight: 400; /* 正常字体粗细 */
      }

      .quick-msg-label-tag:hover {
        color: #0ca9ea;
        text-shadow: 0 0 2px rgba(12, 169, 234, 0.5); /* 添加蓝色半透明阴影 */
        font-weight: 600; /* 加粗字体 */
      }

      .chat-input-send {
        text-align: right;
      }
    }
  }
}

</style>
